package com.example.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.admin.dto.GoodsCategoryAddDTO;
import com.example.admin.dto.GoodsCategoryEditDTO;
import com.example.admin.dto.GoodsCategoryEditSortDTO;
import com.example.common.mapper.GoodsCategoryMapper;
import com.example.admin.service.GoodsCategoryService;
import com.example.admin.vo.GoodsCategoryDetailVO;
import com.example.admin.vo.GoodsCategoryTreeVO;
import com.example.common.Interface.TreeNode;
import com.example.common.exception.ServiceException;
import com.example.common.po.GoodsCategoryPO;
import com.example.common.utils.TreeUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

/**
 * 商品分类
 */
@Service("adminGoodsCategoryServiceImpl")
public class GoodsCategoryServiceImpl extends ServiceImpl<GoodsCategoryMapper, GoodsCategoryPO>
    implements GoodsCategoryService{

    @Autowired
    public GoodsCategoryMapper goodsCategoryMapper;

    @Autowired
    private TreeUtil treeUtil;

    @Resource
    DataSourceTransactionManager dataSourceTransactionManager;

    @Resource
    TransactionDefinition transactionDefinition;

    /**
     * 获取树形列表
     * @return
     */
    @Override
    public List<GoodsCategoryTreeVO> getTree() {
        List<GoodsCategoryPO> list = goodsCategoryMapper.selectList(new QueryWrapper<GoodsCategoryPO>()
                .select("cat_id","pid","cat_name","cat_level","cat_path","sort","is_show")
                .orderByAsc("sort"));
        // 构建树形节点
        List<TreeNode> treeNode = new ArrayList<>();
        Iterator<GoodsCategoryPO> it = list.iterator();
        while (it.hasNext()) {
            TreeNode i = it.next();
            treeNode.add(i);
        }
        //构建扩展属性
        HashMap<String, String> extraAttrList = new HashMap<>();
        extraAttrList.put("catPath", "getCatPath");
        extraAttrList.put("catLevel", "getCatLevel");
        extraAttrList.put("isShow", "getIsShow");
        treeUtil.setIdKey("catId");
        treeUtil.setNameKey("catName");
        treeUtil.setNodeList(treeNode);
        treeUtil.setExtraAttrList(extraAttrList);
        return GoodsCategoryTreeVO.convertToVO(treeUtil.build());
    }

    /**
     * 添加
     * @param goodsCategoryAddDTO
     * @return
     */
    @Override
    public Integer add(GoodsCategoryAddDTO goodsCategoryAddDTO) {
        GoodsCategoryPO insert = new GoodsCategoryPO();
        BeanUtils.copyProperties(goodsCategoryAddDTO,insert);
        insert.setCatLevel(1);
        insert.setCatPath(",");
        insert.setSort(0);
        // 有上级id
        if(goodsCategoryAddDTO.getPid()!=0){
            //查出上级id路径和等级
            GoodsCategoryPO pData = goodsCategoryMapper.selectOne(new QueryWrapper<GoodsCategoryPO>()
                    .select("cat_path","cat_level")
                    .lambda()
                    .eq(GoodsCategoryPO::getCatId,goodsCategoryAddDTO.getPid())
            );
            if(pData==null){
                throw new ServiceException("上级菜单不存在",106);
            }else{
                insert.setCatLevel(insert.getCatLevel()+1);
                insert.setCatPath(pData.getCatPath());
            }
        }
        //开启事务
        TransactionStatus transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
        Integer saveRes = goodsCategoryMapper.insert(insert);
        if (saveRes!=0){
            insert.setCatPath(insert.getCatPath()+insert.getCatId()+",");
            Integer updateRes = goodsCategoryMapper.update(
                    insert,
                    new UpdateWrapper<GoodsCategoryPO>()
                            .lambda().
                            eq(GoodsCategoryPO::getCatId,insert.getCatId()));
            //提交事务
            if(updateRes!=0) {
                dataSourceTransactionManager.commit(transactionStatus);
            }
            return saveRes;
        }else{
            // 回滚事务
            dataSourceTransactionManager.rollback(transactionStatus);
            return 0;
        }
    }

    /**
     * 详情
     * @param catId
     * @return
     */
    @Override
    public GoodsCategoryDetailVO detail(Integer catId) {
        GoodsCategoryPO data = goodsCategoryMapper.selectOne(
                new QueryWrapper<GoodsCategoryPO>()
                        .select("cat_id","pid","cat_name","cat_level","cat_path","sort","is_show")
                        .lambda()
                        .eq(GoodsCategoryPO::getCatId,catId)
        );
        if (data == null) {
            throw new ServiceException("找不到资源", 104);
        }
        GoodsCategoryDetailVO vo = new GoodsCategoryDetailVO();
        BeanUtils.copyProperties(data, vo);
        return vo;
    }

    /**
     * 更新
     * @param goodsCategoryEditDTO
     * @return
     */
    @Override
    public Integer edit(GoodsCategoryEditDTO goodsCategoryEditDTO) {
        GoodsCategoryPO data = goodsCategoryMapper.selectById(goodsCategoryEditDTO.getCatId());
        if(data==null){
            throw new ServiceException("找不到资源", 104);
        }
        GoodsCategoryPO goodsCategoryPO = new GoodsCategoryPO();
        BeanUtils.copyProperties(goodsCategoryEditDTO, goodsCategoryPO);
        return goodsCategoryMapper.updateById(goodsCategoryPO);
    }

    /**
     * 修改排序
     * @param goodsCategoryEditSortDTO
     * @return
     */
    @Override
    public Integer editSort(GoodsCategoryEditSortDTO goodsCategoryEditSortDTO) {
        GoodsCategoryPO goodsCategoryPO = new GoodsCategoryPO();
        BeanUtils.copyProperties(goodsCategoryEditSortDTO, goodsCategoryPO);
        return goodsCategoryMapper.updateById(goodsCategoryPO);
    }

    /**
     * 修改显示状态
     * @param catId
     * @return
     */
    @Override
    public Integer editShow(Integer catId) {
        GoodsCategoryPO data = goodsCategoryMapper.selectById(catId);
        if(data==null){
            throw new ServiceException("找不到资源", 104);
        }
        return goodsCategoryMapper.update(null,
                new UpdateWrapper<GoodsCategoryPO>().
                        lambda()
                        .eq(GoodsCategoryPO::getCatId,catId)
                        .setSql("is_show = !is_show")
        );
    }

    /**
     * 删除
     * @param catId
     * @return
     */
    @Override
    public Integer delete(Integer catId) {
        GoodsCategoryPO data = goodsCategoryMapper.selectById(catId);
        if(data==null){
            throw new ServiceException("找不到资源", 104);
        }
        GoodsCategoryPO validate = goodsCategoryMapper.selectOne(
                new QueryWrapper<GoodsCategoryPO>()
                        .select("cat_id")
                        .like("cat_path",String.format(",%d,",catId))
                        .lambda()
                        .ne(GoodsCategoryPO::getCatId,catId)
                        .last("limit 1")
        );
        if(validate!=null){
            throw new ServiceException("存在子分类无法删除", 104);
        }
        return goodsCategoryMapper.deleteById(catId);
    }
}




